﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
using System.Collections;
using System.Threading;
using System.Data.SqlClient;
using System.Net.Mail;
using System.Net;
using RTXSAPILib;
using System.IO;

namespace ApqAlarm.Forms
{
	public partial class Alarm : Apq.Windows.Forms.DockForm
	{
		private SqlConnection _SqlConnection = null;

		private Thread _tClear = null;

		public Alarm()
		{
			InitializeComponent();
		}

		public override void SetUILang(Apq.UILang.UILang UILang)
		{
			this.Text = UILang["报警"];
			this.TabText = this.Text;

			tsbConnect.Text = UILang["连接到数据库"];
			btnStart.Text = UILang["开始"];
			btnStop.Text = UILang["停止"];
			btnCopy.Text = UILang["复制"];
		}

		private void Alarm_Load(object sender, EventArgs e)
		{
			Apq.Windows.Forms.ListViewHelper.AddBehaivor(listView1);

			// 启动清理线程
			_tClear = Apq.Threading.Thread.StartNewThread(new ThreadStart(WorkerClear));

			// 弹出连接选择界面
			tsbConnect_Click(sender, e);
		}

		private void btnStop_Click(object sender, EventArgs e)
		{
			btnStart.Enabled = true;
			btnStop.Enabled = false;
			Apq.Threading.Thread.Abort(MainBackThread);
		}

		private void btnCopy_Click(object sender, EventArgs e)
		{
			IList lst = listView1.SelectedItems.Count > 0 ? (IList)listView1.SelectedItems : (IList)listView1.Items;
			List<string> lstStrs = new List<string>();
			foreach (ListViewItem lvi in lst)
			{
				string strlvi = lvi.Text;
				if (lvi.SubItems.Count > 1)
				{
					for (int i = 1; i < lvi.SubItems.Count; i++)
					{
						strlvi += "\t" + lvi.SubItems[i].Text;
					}
				}
				lstStrs.Add(strlvi);
			}
			Clipboard.SetText(string.Join(Environment.NewLine, lstStrs.ToArray()));
		}

		private void Random_FormClosing(object sender, FormClosingEventArgs e)
		{

		}

		private void btnStart_Click(object sender, EventArgs e)
		{
			if (_SqlConnection != null)
			{
				btnStart.Enabled = false;
				btnStop.Enabled = true;

				Apq.Threading.Thread.Abort(MainBackThread);
				MainBackThread = Apq.Threading.Thread.StartNewThread(new ThreadStart(Worker));
			}
		}

		private void tsbConnect_Click(object sender, EventArgs e)
		{
			Apq.Windows.Forms.DBConnector dbConnector = new Apq.Windows.Forms.DBConnector();

			// 自动确定不能成功
			/*
			// 选择到MsSql界面
			dbConnector.tabControl1.TabIndex = 1;

			// 尝试自动确定
			dbConnector.btnMsSqlConfirm_Click(sender, e);
			if (dbConnector.DialogResult == System.Windows.Forms.DialogResult.OK)
			{
				_SqlConnection = dbConnector.DBConnection as SqlConnection;
				// 自动开始
				btnStart_Click(sender, e);
			}
			// 让用户设置并确定
			else
			 * */
			{
				if (dbConnector.ShowDialog() == System.Windows.Forms.DialogResult.OK)
				{
					if (dbConnector.DBSelected == Apq.Data.Common.DBProduct.MsSql)
					{
						_SqlConnection = dbConnector.DBConnection as SqlConnection;

						// 自动开始
						btnStart_Click(sender, e);
					}
				}
			}
		}

		private void Worker()
		{
			// 从数据库读取未报警的信息
			SqlDataAdapter _sda = new SqlDataAdapter("SELECT l.ID, l._InTime, l.Type, l.Severity, l.Title, l.STMT, l.Msg, l.AlarmGroupID, l.SrcName, AlarmTypeCaption = ISNULL(t.AlarmTypeCaption,l.Type) FROM dbo.Log_Apq_Alarm l LEFT JOIN dbo.AlarmType t ON l.Type = t.AlarmType WHERE Severity > 10 AND (State & 1) = 0", _SqlConnection);
			_sda.UpdateCommand = new SqlCommand("UPDATE dbo.Log_Apq_Alarm SET State = (State|1) WHERE ID = @ID", _SqlConnection);
			SqlCommand scSkip = new SqlCommand("UPDATE dbo.Log_Apq_Alarm SET State = (State|3) WHERE ID = @ID", _SqlConnection);
			Apq.Data.Common.DbCommandHelper dh = new Apq.Data.Common.DbCommandHelper(_sda.UpdateCommand);
			Apq.Data.Common.DbCommandHelper dhSkip = new Apq.Data.Common.DbCommandHelper(scSkip);

			SqlDataAdapter sda1 = new SqlDataAdapter("SELECT AlarmGroupID, g.UserID, u.Email, u.RTX, u.Mobile FROM dbo.AlarmGroup g INNER JOIN dbo.Users u ON g.UserID = u.UserID WHERE Len(u.Email) > 1", _SqlConnection);
			DataSet dsEmail = new DataSet();

			while (true)
			{
				try
				{
					// 先打开数据库连接
					Apq.Data.Common.DbConnectionHelper.Open(_SqlConnection);

					// 获取Email列表
					dsEmail.Tables.Clear();
					sda1.Fill(dsEmail);

					DataSet ds = new DataSet();
					_sda.Fill(ds);

					foreach (DataRow dr in ds.Tables[0].Rows)
					{
						bool isAlarmed = false;

						// 将读取到的警报显示到界面
						Apq.Windows.Delegates.Action_UI<ListView>(listView1, listView1, delegate(ListView lv)
						{
							string[] ary = new string[6];
							ary[0] = Apq.Convert.ChangeType<DateTime>(dr["_InTime"]).ToString("yyyy-MM-dd HH:mm:ss");
							ary[1] = Apq.Convert.ChangeType<string>(dr["SrcName"]);
							ary[2] = Apq.Convert.ChangeType<string>(dr["AlarmTypeCaption"]);
							ary[3] = Apq.Convert.ChangeType<string>(dr["Severity"]);
							ary[4] = Apq.Convert.ChangeType<string>(dr["Title"]);
							ary[5] = Apq.Convert.ChangeType<string>(dr["STMT"]) + dr["Msg"];
							listView1.Items.Add(new ListViewItem(ary));
							listView1.Items[listView1.Items.Count - 1].EnsureVisible();
						});

						int Severity = Apq.Convert.ChangeType<int>(dr["Severity"]);

						#region 邮件
						// 所有都发邮件
						// 设置好Smtp
						/* 使用Gmail
						SmtpClient _SmtpClient = new SmtpClient();
						_SmtpClient.Host = "smtp.gmail.com";
						_SmtpClient.Port = 587;
						_SmtpClient.EnableSsl = true;
						_SmtpClient.Credentials = new NetworkCredential("Amwpfiqvy@gmail.com", "921114_google");
						 * */
						SmtpClient _SmtpClient = new SmtpClient();
						_SmtpClient.Host = "mail.shengyou.com.cn";
						_SmtpClient.Credentials = new NetworkCredential("alarm", "syalarm");

						MailMessage mailMsg = new MailMessage();
						mailMsg.From = new MailAddress("alarm@shengyou.com.cn", "报警程序");

						// 根据AlarmGroupID查找所有目标Email地址并加入To
						DataView dvEmail = new DataView(dsEmail.Tables[0]);
						dvEmail.RowFilter = "AlarmGroupID = " + dr["AlarmGroupID"];
						foreach (DataRowView drv in dvEmail)
						{
							string strEmail = Apq.Convert.ChangeType<string>(drv["Email"]);
							if (!string.IsNullOrWhiteSpace(strEmail))
							{
								mailMsg.To.Add(strEmail);
							}
						}

						if (mailMsg.To.Count > 0)
						{
							mailMsg.Subject = Apq.Convert.ChangeType<string>(dr["Title"]);
							mailMsg.Body = "\r\n时间:" + Apq.Convert.ChangeType<DateTime>(dr["_InTime"]).ToString("yyyy-MM-dd HH:mm:ss") +
								"\r\n来源:" + Apq.Convert.ChangeType<string>(dr["SrcName"]) +
								"\r\n\r\nSTMT:\r\n" + Apq.Convert.ChangeType<string>(dr["STMT"]) +
								"\r\n\r\n内容:\r\n" + Apq.Convert.ChangeType<string>(dr["Msg"]);

							_SmtpClient.SendAsync(mailMsg, new object());
							isAlarmed = true;
						}
						#endregion

						#region RTX
						// 15以上的发RTX
						if (Severity >= 16)
						{
							RTXSAPIRootObjClass RootObj = new RTXSAPIRootObjClass();
							//RootObj.ServerIP = "xxol.3322.org";// 盛游内网192.168.1.68,xxol.3322.org,ns8.ym6.cn
							//RootObj.ServerPort = 16256; // 设置服务器端口，默认为8006
							string strIP = GlobalObject.XmlConfigChain[this.GetType(), "RtxServer"];
							if (!Apq.String.IsIP4(strIP))
							{
								// 将域名解析为IP
								IPHostEntry ipHostEntry = Dns.GetHostEntry(strIP);
								if (ipHostEntry.AddressList.Length > 0)
								{
									strIP = ipHostEntry.AddressList[0].ToString();
								}
							}
							RootObj.ServerIP = strIP;
							RootObj.ServerPort = Apq.Convert.ChangeType<short>(GlobalObject.XmlConfigChain[this.GetType(), "RtxServerPort"], 8006);

							//IRTXSAPIObj APIObj = RootObj.CreateAPIObj();      // 通过根对象创建应用对象
							//IRTXSAPIMessage MsgObj = APIObj.CreateMessage(); //通过应用对象创建消息对象
							//MsgObj.AppName = "报警";
							//MsgObj.Content = Apq.Convert.ChangeType<string>(dr["Msg"]);

							// 根据AlarmGroupID查找所有目标RTX地址并发送消息
							DataView dvRtx = new DataView(dsEmail.Tables[0]);
							dvRtx.RowFilter = "AlarmGroupID = " + dr["AlarmGroupID"];
							foreach (DataRowView drv in dvRtx)
							{
								string strRTX = Apq.Convert.ChangeType<string>(drv["RTX"]);
								string strRtxMsg = "\r\n时间:" + Apq.Convert.ChangeType<DateTime>(dr["_InTime"]).ToString("yyyy-MM-dd HH:mm:ss") +
									"\r\n来源:" + Apq.Convert.ChangeType<string>(dr["SrcName"]) +
									"\r\n\r\n内容:\r\n" + Apq.Convert.ChangeType<string>(dr["Msg"]);

								if (!string.IsNullOrWhiteSpace(strRTX))
								{
									try
									{
										//Apq.GlobalObject.ApqLog.Debug("ID=" + dr["ID"] + ",RTX=" + strRTX);
										RootObj.SendNotify(
											strRTX,
											Apq.Convert.ChangeType<string>(dr["Title"]),
											0,
											strRtxMsg
										);
										isAlarmed = true;
									}
									catch (Exception ex)
									{
										Apq.GlobalObject.ApqLog.Error("发送RTX消息失败", ex);
									}
								}
							}
						}
						#endregion

						#region 短信
						// 20以上发短信
						if (Severity >= 20)
						{
							// 根据AlarmGroupID查找所有目标Mobile地址并加入列表
							DataView dvMobile = new DataView(dsEmail.Tables[0]);
							dvMobile.RowFilter = "AlarmGroupID = " + dr["AlarmGroupID"];
							List<string> lstMobile = new List<string>();
							foreach (DataRowView drv in dvMobile)
							{
								string strMobile = Apq.Convert.ChangeType<string>(drv["Mobile"]);
								if (!string.IsNullOrWhiteSpace(strMobile))
								{
									lstMobile.Add(strMobile);
								}
							}

							if (lstMobile.Count > 0)
							{
								string strContent = Apq.Convert.ChangeType<DateTime>(dr["_InTime"]).ToString("yyyy-MM-dd HH:mm:ss") +
									"[" + Apq.Convert.ChangeType<string>(dr["SrcName"]) + "]\r\n" +
									Apq.Convert.ChangeType<string>(dr["Title"]);

								// 中国短信中心
								bool b = c123.Send(string.Join(",", lstMobile), strContent);

								// 商通
								//bool b = i2b.Send(string.Join(",", lstMobile), strContent);

								if (b)
								{
									isAlarmed = true;
								}
							}
						}
						#endregion

						// 报警后将状态置为已报警
						if (isAlarmed)
						{
							dh.AddParameter("@ID", dr["ID"]);
							Apq.Data.Common.DbConnectionHelper.Open(_SqlConnection);
							_sda.UpdateCommand.ExecuteNonQuery();
						}
						else if (0.Equals(dr["AlarmGroupID"]))
						{
							dhSkip.AddParameter("@ID", dr["ID"]);
							Apq.Data.Common.DbConnectionHelper.Open(_SqlConnection);
							scSkip.ExecuteNonQuery();
						}
					}
				}
				catch (Exception ex)
				{
					Apq.GlobalObject.ApqLog.Error("报警失败", ex);
				}
				finally
				{
					Apq.Data.Common.DbConnectionHelper.Close(_SqlConnection);
				}

				Thread.Sleep(60000);//1分钟一次
			}
		}

		private void Alarm_FormClosing(object sender, FormClosingEventArgs e)
		{
			btnStop_Click(sender, e);

			// 停止清理线程
			Apq.Threading.Thread.Abort(_tClear);
		}

		private void WorkerClear()
		{
			while (true)
			{
				try
				{
					Apq.Windows.Delegates.Action_UI<ListView>(listView1, listView1, delegate(ListView lv)
					{
						while (listView1.Items.Count > 1000)
						{
							listView1.Items.RemoveAt(0);
						}
					});
				}
				catch { }

				Thread.Sleep(5 * 60000);//5分钟一次
			}
		}
	}
}